package backend.Algoritmos;


import java.awt.List;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Vector;

import com.dp.client.dto.Fecha;

import backend.Utiles.DataFactory;
import backend.estructuras.common.Almacen;
import backend.estructuras.common.Conexion;
import backend.estructuras.common.Continente;
import backend.estructuras.common.Paquete;

public class Simulator {
	Solver solver;
	GeneradorDeEstadisticas estadisticas;
	Fecha fechaInicio = new Fecha(0);
	Fecha fechaFin;
	
	public void setDias(int dias){
		fechaFin = Fecha.suma(fechaInicio, new Fecha(dias * 24));
	}
	public Simulator(Solver solver){
		this.solver = solver;
	}
	public Solver getSolver(){
		return solver;
	}
	public void cargarDatosDesdeBD(){
		solver.cargarDatosDesdeBD(true);
	}
	
	public void run(){
		//limpia todo
		solver.vuelos = new ArrayList<>();
		solver.paquetesEstimados = new ArrayList<>();
		solver.paquetesFijos = new ArrayList<>();
		solver.paquetesSinRuta = new ArrayList<>();
		solver.limpiaEstadisticas();
		//Generar paquetes
		int horas = 0;
		Fecha dif = Fecha.resta(fechaFin, fechaInicio);
		horas = dif.getDia() * 24 + dif.getHora();
		solver.generaVuelosEnIntervaloDeTiempo(fechaInicio, horas);
		solver.generaPaquetesEstimadosParaIntervaloDeTiempo(fechaInicio, fechaFin);
		solver.generaYEjecutaRutasParaIntervaloDeTiempo(fechaInicio, fechaFin);
		runEstadisticas();
	}
	
	public void run(InputStream inputStream){
		@SuppressWarnings("resource")
		Scanner in = new Scanner(inputStream);
		int n;
		//Meter fecha inicial y final y de inicio del universo
		in.nextLine();
		Fecha fechaInicio = parseFecha(in.nextLine());
		solver.setFechaInicialSimulacion(fechaInicio);
		solver.setFechaInicioUniverso(fechaInicio);
		//Meter fecha fin
		Fecha fechaFin = parseFecha(in.nextLine());
		//Meter continentes
		in.nextLine();
		n = Integer.parseInt(in.nextLine());
		while(n-- > 0){
			String continente = in.nextLine();
			solver.addContinente(continente);
		}
		//Meter almacenes
		in.nextLine();
		n = Integer.parseInt(in.nextLine());
		int ID = 0;
		while(n-- > 0){
			String nombre = in.nextLine();
			String continente = in.nextLine();
			int capacidadInicial = Integer.parseInt(in.nextLine());
			int id = ++ID;
			solver.addAlmacen(nombre, capacidadInicial, solver.getContinentePorNombre(continente), id, 0, 0);
		}
		//Meter conexiones
		in.nextLine();
		n = Integer.parseInt(in.nextLine());
		ID = 0;
		while(n-- > 0){
			String origen = in.nextLine();
			String destino = in.nextLine();
			int hora = Integer.parseInt(in.nextLine());
			int capacidadInicial = Integer.parseInt(in.nextLine());
			String patron = in.nextLine();
			int id = ++ID;
			if(patron.length() != 7){
				System.err.println("El patron " + patron + " no tiene longitud 7 para los dias de la semana.");
				return;
			}
			boolean[] frecuencia = new boolean[7];
			for(int i = 0; i < 7; i++) frecuencia[i] = patron.charAt(i) == '0' ? false : true;
			//boolean 
			solver.addConexion(solver.getAlmacenPorNombre(origen),
					           solver.getAlmacenPorNombre(destino),
					           hora,
					           frecuencia,
					           capacidadInicial,
					           id);
		}
		
		//meter distribuciones y data historica
		in.nextLine();
		for(int i = 0; i < solver.getAlmacenes().size(); i++)
			for(int j = 0; j < solver.getAlmacenes().size(); j++) if(i != j){
				String origen = in.nextLine();
				String destino = in.nextLine();
				int media = Integer.parseInt(in.nextLine());
				double varianza = Double.parseDouble(in.nextLine());
				solver.addDistribucion(solver.getAlmacenPorNombre(origen),
									   solver.getAlmacenPorNombre(destino), media, varianza);
			}
		//Generar paquetes
		int horas = 0;
		Fecha dif = Fecha.resta( fechaFin , fechaInicio );
		horas = dif.getDia() * 24 + dif.getHora();

		System.out.println("" + solver.getNombre());
		solver.generaVuelosEnIntervaloDeTiempo(fechaInicio, horas);
		solver.generaPaquetesEstimadosParaIntervaloDeTiempo(fechaInicio, fechaFin);
		solver.generaYEjecutaRutasParaIntervaloDeTiempo(fechaInicio, fechaFin);
		in.close();
		
		runEstadisticas();
	}
	
	private Fecha parseFecha(String nextLine) {
		StringTokenizer tokenizer = new StringTokenizer(nextLine);
		int dia = Integer.parseInt(tokenizer.nextToken());
		int hora = Integer.parseInt(tokenizer.nextToken());
		return new Fecha(dia, hora);
	}
	public String runEstadisticas(){
		estadisticas = new GeneradorDeEstadisticas(solver);
		estadisticas.process();
		estadisticas.print();
		return estadisticas.printToString();
	}
}
